//////////////////////////////////////////////////////////////////////////////
// AXI slave for l2 cache
// Application-specific cache slave,  
//     
// Features:
//          .Alinged transfer
//          .wrapping cache line bursts (Only)
//          .Out of order read depth 1
//          .Out of order write depth 1
// Parameters:
//          SLAVE_ID_BITS   : default 4
//          AXI_ADDR_WIDTH  : default 32
//----------------------------------------------------------------------------
//Note: 
//       
//          
//////////////////////////////////////////////////////////////////////////////

//------------------------------------------------------------------------------
// AXI Standard Defines
//------------------------------------------------------------------------------
// ALEN Encoding
`define AXI_ALEN_1            4'b0000
`define AXI_ALEN_2            4'b0001
`define AXI_ALEN_3            4'b0010
`define AXI_ALEN_4            4'b0011
`define AXI_ALEN_5            4'b0100
`define AXI_ALEN_6            4'b0101
`define AXI_ALEN_7            4'b0110
`define AXI_ALEN_8            4'b0111
`define AXI_ALEN_9            4'b1000
`define AXI_ALEN_10           4'b1001
`define AXI_ALEN_11           4'b1010
`define AXI_ALEN_12           4'b1011
`define AXI_ALEN_13           4'b1100
`define AXI_ALEN_14           4'b1101
`define AXI_ALEN_15           4'b1110
`define AXI_ALEN_16           4'b1111

// ASIZE Enconding
`define AXI_ASIZE_8           3'b000
`define AXI_ASIZE_16          3'b001
`define AXI_ASIZE_32          3'b010
`define AXI_ASIZE_64          3'b011
`define AXI_ASIZE_128         3'b100
`define AXI_ASIZE_256         3'b101
`define AXI_ASIZE_512         3'b110
`define AXI_ASIZE_1024        3'b111

// ABURST Encoding
`define AXI_ABURST_FIXED      2'b00
`define AXI_ABURST_INCR       2'b01
`define AXI_ABURST_WRAP       2'b10

// ALOCK Encoding
`define AXI_ALOCK_NOLOCK      2'b00
`define AXI_ALOCK_EXCL        2'b01
`define AXI_ALOCK_LOCKED      2'b10

// RRESP / BRESP Encoding
`define AXI_RESP_OKAY         2'b00
`define AXI_RESP_EXOKAY       2'b01
`define AXI_RESP_SLVERR       2'b10
`define AXI_RESP_DECERR       2'b11

module l2cache_axi_slave 
#(
    parameter AXI_SLAVE_DATA_WIDTH  =32,
    parameter AXI_SLAVE_ADDR_WIDTH  =32,
    parameter AXI_SLAVE_ID_WIDTH    =4
)  
(
    input                       ACLK,
    input                       ARESETn,

    //-------------------------------------------------------------------------
    // AXI Slave port                  
    //-------------------------------------------------------------------------
    // AXI write address channel
    input [AXI_SLAVE_ID_WIDTH-1:0]      AWIDS,
    input [AXI_SLAVE_ADDR_WIDTH-1:0]    AWADDRS,
    input [3:0]                 AWLENS,
    input [2:0]                 AWSIZES,
    input [1:0]                 AWBURSTS,
    input [1:0]                 AWLOCKS,
    input [3:0]                 AWCACHES,
    input [2:0]                 AWPROTS,
    input                       AWVALIDS,
    output                      AWREADYS,
    // AXI write data channel
    input [AXI_SLAVE_ID_WIDTH-1:0]      WIDS,
    input [AXI_SLAVE_DATA_WIDTH-1:0]    WDATAS,
    input [7:0]                 WSTRBS,
    input                       WLASTS,
    input                       WVALIDS,
    output                      WREADYS,
    // AXI write response channel
    output [AXI_SLAVE_ID_WIDTH-1:0]     BIDS,
    output [1:0]                BRESPS,
    output                      BVALIDS,
    input                       BREADYS,
    // AXI read address channel
    input [AXI_SLAVE_ID_WIDTH-1:0]   ARIDS,
    input [31:0]                ARADDRS,
    input [3:0]                 ARLENS,
    input [2:0]                 ARSIZES,
    input [1:0]                 ARBURSTS,
    input [1:0]                 ARLOCKS,
    input [3:0]                 ARCACHES,
    input [2:0]                 ARPROTS,
    input                       ARVALIDS,
    output    reg                  ARREADYS,
    // AXI read data channel
    output [AXI_SLAVE_ID_WIDTH-1:0]  RIDS,
    output [AXI_SLAVE_DATA_WIDTH-1:0] RDATAS,
    output [1:0]                RRESPS,
    output                      RLASTS,
    output                      RVALIDS,
    input                       RREADYS,

    // Custom interface
    output     reg                 rqst,           // Output decoded Read address is valid 
    input                       grant,           // Response addr_valid 
    output  [AXI_SLAVE_ADDR_WIDTH-1:0]              addr                  // Decoded read address
);

reg state; 
reg [AXI_SLAVE_ID_WIDTH-1:0]   ARIDS_reg	;
reg [31:0]                ARADDRS_reg;
reg [3:0]                 ARLENS_reg;
reg [2:0]                 ARSIZES_reg;
reg [1:0]                 ARBURSTS_reg;
reg [1:0]                 ARLOCKS_reg;
reg [3:0]                 ARCACHES_reg;
reg [2:0]                 ARPROTS_reg;
reg                       ARVALIDS_reg;

// AXI slave enable signal
assign en_axis = (ARVALIDS | AWVALIDS) ? 1 : 0;   

// Gate input signals

always @(posedge ACLK or negedge ARESETn) begin
    if ( !ARESETn) begin
    ARREADYS    = 1'b0;
    ARADDRS_reg = 1'b0;
    ARLENS_reg  = 1'b0;
    ARBURSTS_reg= 1'b0;
    ARSIZES_reg = 1'b0;
    ARLOCKS_reg = 1'b0;
    ARCACHES_reg= 1'b0;
    ARPROTS_reg = 1'b0;

    end else begin
        case (state)
            1'b0 : begin
                if (ARVALIDS == 1'b1) begin
                    state       = 1'b1;
                    ARREADYS    = 1'b0;
                    /*
                    ARADDRS_reg = ARADDRS_reg;
                    ARLENS_reg  = ARLENS_reg;
                    ARBURSTS_reg= ARBURSTS_reg;
                    ARSIZES_reg = ARSIZES_reg;
                    ARLOCKS_reg = ARLOCKS_reg;
                    ARCACHES_reg= ARCACHES_reg;
                    ARPROTS_reg = ARPROTS_reg;*/

                end else begin
                    state = 1'b0;
                    ARREADYS = 1'b1;

                    ARADDRS_reg = ARADDRS;
                    ARLENS_reg  = ARLENS;
                    ARBURSTS_reg= ARBURSTS;
                    ARSIZES_reg = ARSIZES;
                    ARLOCKS_reg = ARLOCKS;
                    ARCACHES_reg= ARCACHES;
                    ARPROTS_reg = ARPROTS;
                end
            end

               
            1'b1 : begin
                // GENERATE ADDR_MEM AND RQST SIGNAL TRY TO GET ACCESSING GRANT
                rqst <= 1'b1;
                    
            end
        endcase
    end
end
/*
        if (ARVALIDS == 1'b1) begin
            request <= 1'b1;

            if (ARBURSTS_reg = `AXI_ABURST_WRAP) begin
                if (len_cnt < ARLENS_reg) begin
                    len_cnt = len_cnt + 1'b1;
            end else begin  // Ignore FIXED and INCR burst
                state = 1'b0;
            end
*/
endmodule
